package com.example.myapplication.data

import com.example.myapplication.api.SinaFinanceApi
import com.example.myapplication.model.Stock
import com.example.myapplication.model.StockPrice
import kotlinx.coroutines.delay

/**
 * 股票数据仓库（支持真实API）
 * 提供股票列表和历史数据
 * 
 * 使用方式：
 * 1. 将此文件重命名为 StockRepository.kt 替换原文件
 * 2. 或在 StockViewModel 中切换使用此类
 */
class StockRepositoryWithApi(private val useMockData: Boolean = false) : IStockRepository {
    
    private val sinaApi = SinaFinanceApi()
    
    // A股热门股票代码列表
    private val popularSymbols = listOf(
        "600519", // 贵州茅台
        "000858", // 五粮液
        "601318", // 中国平安
        "600036", // 招商银行
        "000651", // 格力电器
        "002594", // 比亚迪
        "600809", // 山西汾酒
        "300750", // 宁德时代
        "603259", // 药明康德
        "601888"  // 中国中免
    )
    
    /**
     * 获取热门股票列表
     */
    override suspend fun getPopularStocks(): List<Stock> {
        return if (useMockData) {
            getMockStocks()
        } else {
            getRealStocks()
        }
    }
    
    /**
     * 从真实API获取股票数据
     */
    private suspend fun getRealStocks(): List<Stock> {
        return try {
            // 将代码转换为新浪格式（添加sh/sz前缀）
            val symbols = popularSymbols.map { sinaApi.normalizeSymbol(it) }
            sinaApi.getRealTimeData(symbols)
        } catch (e: Exception) {
            e.printStackTrace()
            // 如果API失败，返回模拟数据作为备用
            getMockStocks()
        }
    }
    
    /**
     * 获取股票历史价格数据（真实日K线）
     * 从2025年9月1日开始到今天的真实数据
     */
    override suspend fun getStockHistory(symbol: String, days: Int): List<StockPrice> {
        return if (useMockData) {
            getMockHistory(symbol, days)
        } else {
            getRealHistory(symbol, days)
        }
    }
    
    /**
     * 从真实API获取历史数据（网易财经日K线）
     * 如果API失败，自动降级到模拟数据
     */
    private suspend fun getRealHistory(symbol: String, days: Int): List<StockPrice> {
        return try {
            val normalizedSymbol = sinaApi.normalizeSymbol(symbol)
            val history = sinaApi.getHistoryData(normalizedSymbol, days)
            
            android.util.Log.d("📊真实数据", "获取到${history.size}条真实日K线数据")
            
            // 如果真实API返回空数据，自动降级到模拟数据
            if (history.isEmpty()) {
                android.util.Log.w("📊真实数据", "⚠️ 真实API无数据，自动降级到模拟数据")
                getMockHistory(symbol, days)
            } else {
                history
            }
        } catch (e: Exception) {
            e.printStackTrace()
            android.util.Log.e("📊真实数据", "❌ 获取真实数据失败: ${e.message}，自动降级到模拟数据")
            // 失败时返回模拟数据，确保应用正常运行
            getMockHistory(symbol, days)
        }
    }
    
    /**
     * 搜索股票
     */
    override suspend fun searchStocks(query: String): List<Stock> {
        delay(300)
        
        val allStocks = getPopularStocks()
        return allStocks.filter { 
            it.symbol.contains(query, ignoreCase = true) || 
            it.name.contains(query, ignoreCase = true)
        }
    }
    
    // ========== 以下是模拟数据方法（作为备用） ==========
    
    private suspend fun getMockStocks(): List<Stock> {
        delay(500)
        
        return listOf(
            Stock("600519", "贵州茅台", 1680.50, 15.30, 0.92, 125000000, 2100000000000.0, "白酒"),
            Stock("000858", "五粮液", 178.20, -2.10, -1.16, 89000000, 680000000000.0, "白酒"),
            Stock("601318", "中国平安", 45.80, 0.50, 1.10, 156000000, 830000000000.0, "保险"),
            Stock("600036", "招商银行", 38.60, 0.35, 0.91, 198000000, 950000000000.0, "银行"),
            Stock("000651", "格力电器", 36.20, -0.80, -2.16, 142000000, 210000000000.0, "家电"),
            Stock("002594", "比亚迪", 285.40, 8.60, 3.11, 168000000, 820000000000.0, "新能源汽车"),
            Stock("600809", "山西汾酒", 268.50, 5.20, 1.98, 78000000, 330000000000.0, "白酒"),
            Stock("300750", "宁德时代", 168.50, -3.20, -1.86, 192000000, 750000000000.0, "电池"),
            Stock("603259", "药明康德", 68.90, 1.25, 1.85, 56000000, 210000000000.0, "医药"),
            Stock("601888", "中国中免", 92.30, -1.50, -1.60, 84000000, 180000000000.0, "零售")
        )
    }
    
    /**
     * 获取模拟历史数据（周线）
     * 从2025年9月1日开始，一直更新到当前最新一周
     */
    private suspend fun getMockHistory(symbol: String, days: Int): List<StockPrice> {
        delay(800)
        
        val prices = mutableListOf<StockPrice>()
        var basePrice = when {
            symbol.startsWith("6005") -> 1650.0
            symbol.startsWith("0008") -> 175.0
            symbol.startsWith("6013") || symbol.startsWith("6000") -> 45.0
            symbol.startsWith("0006") -> 35.0
            symbol.startsWith("0025") -> 280.0
            symbol.startsWith("6008") -> 265.0
            symbol.startsWith("3007") -> 170.0
            symbol.startsWith("6032") -> 70.0
            symbol.startsWith("6018") -> 95.0
            else -> 50.0
        }
        
        // 设置起始日期为2025年9月1日（星期一）
        val startCalendar = java.util.Calendar.getInstance()
        startCalendar.set(2025, java.util.Calendar.SEPTEMBER, 1, 9, 30, 0)
        startCalendar.set(java.util.Calendar.MILLISECOND, 0)
        
        // 调整到最近的周一
        while (startCalendar.get(java.util.Calendar.DAY_OF_WEEK) != java.util.Calendar.MONDAY) {
            startCalendar.add(java.util.Calendar.DAY_OF_YEAR, 1)
        }
        
        // 获取当前时间，计算到今天为止有多少周
        val currentCalendar = java.util.Calendar.getInstance()
        val startTime = startCalendar.timeInMillis
        val currentTime = currentCalendar.timeInMillis
        
        // 计算从9月1日到现在的周数
        val totalWeeks = ((currentTime - startTime) / (7 * 24 * 60 * 60 * 1000L)).toInt() + 1
        val weeksToGenerate = minOf(totalWeeks, 52) // 最多生成52周（1年）
        
        val trend = kotlin.random.Random.nextDouble(-0.2, 0.4)
        val calendar = startCalendar.clone() as java.util.Calendar
        
        for (i in 0 until weeksToGenerate) {
            val weekTimestamp = calendar.timeInMillis
            
            // 不生成未来的数据
            if (weekTimestamp > currentTime) {
                break
            }
            
            val weeklyChange = kotlin.random.Random.nextDouble(-0.08, 0.08) + trend / weeksToGenerate
            basePrice *= (1 + weeklyChange)
            
            val open = basePrice * (1 + kotlin.random.Random.nextDouble(-0.02, 0.02))
            val close = basePrice * (1 + kotlin.random.Random.nextDouble(-0.03, 0.03))
            val high = maxOf(open, close) * (1 + kotlin.random.Random.nextDouble(0.02, 0.06))
            val low = minOf(open, close) * (1 - kotlin.random.Random.nextDouble(0.02, 0.06))
            val volume = kotlin.random.Random.nextLong(500000000, 1500000000)
            
            prices.add(
                StockPrice(
                    timestamp = weekTimestamp,
                    open = open,
                    high = high,
                    low = low,
                    close = close,
                    volume = volume
                )
            )
            
            calendar.add(java.util.Calendar.DAY_OF_YEAR, 7)
        }
        
        return prices
    }
}

